Skip to content

fix: correlate invalid JSON-RPC envelope errors with the original request id#2852

Open
anneheartrecord wants to merge 1 commit into
modelcontextprotocol:mainfrom
anneheartrecord:fix/2848-preserve-request-id-on-invalid-body
Open

fix: correlate invalid JSON-RPC envelope errors with the original request id#2852
anneheartrecord wants to merge 1 commit into
modelcontextprotocol:mainfrom
anneheartrecord:fix/2848-preserve-request-id-on-invalid-body

Conversation

@anneheartrecord

Copy link
Copy Markdown

Fixes #2848

When an incoming message is valid JSON but fails JSON-RPC envelope validation (e.g. "jsonrpc": "1.0", a missing jsonrpc field, or a non-string method), the error response could not be correlated with the originating request:

  • stdio: the server transport forwarded the exception in-stream and never answered, so the client got no response for its request id.
  • Streamable HTTP: the server replied 400 with a JSON-RPC error using a null id ("server-error" on v1.x), breaking client-side request/response correlation.

This PR extracts the request id best-effort from the raw parsed payload (shared helper extract_raw_request_id; only spec-valid id types are accepted — strings and non-bool integers) and preserves it in the error response on both transports, falling back to a null id per the JSON-RPC 2.0 spec when no valid id can be extracted. The stdio transport now also answers unparseable lines with -32700 Parse error (null id), matching the HTTP transport's existing parse-error behavior. Envelope-invalid messages are now reported as -32600 Invalid Request instead of -32602 Invalid params, matching JSON-RPC 2.0 error code semantics (the issue's three repro cases are envelope violations, not parameter errors).

Tests cover all three repro cases from the issue on both transports, plus the null-id fallback (unextractable id and unparseable body). Full suite, ruff, and pyright pass.

…uest id

When an incoming message is valid JSON but fails JSON-RPC envelope
validation, the error response previously could not be correlated with
the originating request: the stdio server transport dropped the message
with no response at all, and the Streamable HTTP transport replied with
a null id.

Extract the request id best-effort from the raw parsed payload and
preserve it in the error response on both transports, falling back to a
null id (per the JSON-RPC 2.0 spec) when no valid id can be extracted.
The stdio transport now also answers unparseable lines with a Parse
error (-32700, null id), and both transports report envelope-invalid
messages as Invalid Request (-32600) instead of Invalid params (-32602),
matching the JSON-RPC 2.0 error code semantics.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Invalid JSON-RPC envelope errors are not correlated with the original request id

1 participant